//
//  main.m
//  07-内存管理
//
//  Created by dllo on 16/7/12.
//  Copyright © 2016年 高雅馨. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "South.h"
int main(int argc, const char * argv[]) {
    /**
     *  1⃣️内存问题:
     * 1. 内存溢出:内存过多导致溢出,产生crash
     * 2. 野指针: 指针指向未知区域,指向一块被释放的内存(过度释放)
     * 内存管理方式(ios)
     * 1. 垃圾回收机制:只有Mac上有
     * 2. MRC: 手动管理引用计数
     * 3. ARC:自动内存管理机制引用计数(现在常用)
     *             将ARC 环境改为MRC环境: Buildsettings -> 搜索auto -> ARC -> NO
     * 注意: ARC基于MRC进行管理,系统帮程序员添加了内存管理的内容
     * 当遇到retain, alloc, copy需要进行内存管理
     */
    /*
     * 1 当使用alloc, copy时, 对象的'引用计数器'由0->1
     * 2 当使用retain方法时,对象的'引用计数器'的值+1
     * 3 当使用alloc, copy, retain时,需要使用release和autorelease方法,让对象引用计数器的值-1
     * 4 当对象的引用计数器的值为0时,对象被销毁,系统会调用对应的dealloc方法
     * 注意: 内存管理, 对对象操作完成后,在进行释放
     */
    South *south = [[South alloc] init];
    NSLog(@"%lu", (unsigned long)south.retainCount);
  //  [south release];
    NSLog(@"%lu", (unsigned long)south.retainCount);
    // release方法的作用不是销毁对象!!!
#warning mark: retainCount获取的值仅供参考,并且获取不到0
    // 集合类型, 会对 对象进行引用计数
    // addObject会对其保存的对象进行引用计数器+1的操作
    // removeObject 对 对象进行引用技术 -1
    NSMutableArray *array = [NSMutableArray arrayWithObjects:south, nil];
    NSLog(@"向数组中添加后的引用计数%ld", array.retainCount);
    [array removeAllObjects];
    NSLog(@"向数组中移除后的引用计数%ld", array.retainCount);
    
    /**
     *  2⃣️ARC
     * 1. strong(ARC, 强引用引用计数 +1) weak(应用与对象类型(NSObject子类)弱引用, 在对象被释放时会自动置空)
     * 2. retain(MRC, 强引用引用计数 +1)
     * 3. copy(拷贝, 把对象拷贝一份, 原来的引用计数不变,新的+1)
     * 4. assign(应用于简单的数据类型, 不会产生引用计数)
     */
    /**
     *  使用协议
     1 声明一个协议
     2 遵循协议
     3 实现协议里面的方法
     *  验证协议方法
     * 签订协议NSCoping
     * 实现协议方法copyWithZone
     */
    South *newSouth = [south copy];
    NSLog(@"new:%@-south:%@", newSouth, south);
    newSouth.name = @"🐶";
    newSouth.sexual = @"母";
    // KVC Key-Value-Coding 键值编码 间接访问成员的方式
    // 只要是NSObject的子类就包含这些方法
    // valueForKey
    id name = [newSouth valueForKey:@"name"];
    NSLog(@"%@", name);
    [newSouth setValue:@"🐵" forKey:@"name"];
    NSLog(@"%@", newSouth.name);
    
    South *southNorth = [[South alloc] init] ;
    southNorth.southNorth = newSouth;
   id northName = [southNorth valueForKeyPath:@"southNorth.name"];
    NSLog(@"%@", northName);
    [southNorth setValue:@"🐷" forKeyPath:@"southNorth.name"];
    NSLog(@"%@", southNorth.southNorth.name);
    [northName release];

    NSDictionary *dic = [[NSDictionary alloc] initWithObjectsAndKeys:@"123456789", @"id", @"收点卡的卢卡斯", @"description", nil];
    South *dicSorth = [[South alloc] init];
    [dicSorth setValuesForKeysWithDictionary:dic];
    
    // 如果在ARC工程下使用MRC的文件
    // -fno-objc-arc
    // 如果在MRC的工程下使用ARC的文件
    // -fobjc-arc
    return 0;
}

